home *** CD-ROM | disk | FTP | other *** search
/ All for Cell Phones: Sony Ericsson / Sony-Ericsson 2004.iso / Java / Mail For Me / Mail4ME.jar / de / trantor / mail / MimeDecoder.class (.txt) < prev    next >
Encoding:
Java Class File  |  2001-10-21  |  5.4 KB  |  201 lines

  1. package de.trantor.mail;
  2.  
  3. import java.io.ByteArrayOutputStream;
  4. import java.util.Vector;
  5.  
  6. public class MimeDecoder {
  7.    private Vector lines;
  8.    private int begin;
  9.    private int end;
  10.    private String type;
  11.    private String name;
  12.    private String encoding;
  13.    private Vector parts;
  14.  
  15.    public MimeDecoder(Message message) {
  16.       this.init(message.getLines(), 0, message.getLines().size());
  17.    }
  18.  
  19.    private MimeDecoder(MimeDecoder parent, int begin, int end) {
  20.       this.init(parent.lines, begin, end);
  21.    }
  22.  
  23.    private void init(Vector lines, int begin, int end) {
  24.       this.lines = lines;
  25.       String s = (String)lines.elementAt(begin);
  26.  
  27.       while(!s.equals("")) {
  28.          ++begin;
  29.  
  30.          while(begin < end) {
  31.             String t = (String)lines.elementAt(begin);
  32.             if (!t.startsWith(" ") && !t.startsWith("\t")) {
  33.                break;
  34.             }
  35.  
  36.             s = s + t;
  37.             ++begin;
  38.          }
  39.  
  40.          String name = Message.getStringName(s).toLowerCase();
  41.          if (!name.equals("content-type")) {
  42.             if (name.equals("content-transfer-encoding")) {
  43.                this.encoding = Message.getStringValue(s);
  44.             }
  45.          } else {
  46.             String[] elements = Message.getStringElements(Message.getStringValue(s));
  47.             this.type = elements[0];
  48.  
  49.             for(int i = 1; i < elements.length; ++i) {
  50.                if (this.type.startsWith("multipart/") && getStringName(elements[i]).equals("boundary")) {
  51.                   String boundary = "--" + getStringValue(elements[i]);
  52.                   this.parts = new Vector();
  53.  
  54.                   for(int j = begin; j < end; ++j) {
  55.                      if (this.getLine(j).startsWith(boundary)) {
  56.                         this.parts.addElement(new Integer(j));
  57.                      }
  58.                   }
  59.                } else if (getStringName(elements[i]).equals("name")) {
  60.                   this.name = getStringValue(elements[i]);
  61.                }
  62.             }
  63.          }
  64.  
  65.          if (begin < end) {
  66.             s = (String)lines.elementAt(begin);
  67.          } else {
  68.             s = "";
  69.          }
  70.       }
  71.  
  72.       this.begin = begin;
  73.       this.end = end;
  74.    }
  75.  
  76.    private String getLine(int index) {
  77.       return (String)this.lines.elementAt(index);
  78.    }
  79.  
  80.    public int getBodyLineCount() {
  81.       return this.end - this.begin;
  82.    }
  83.  
  84.    public String getBodyLine(int index) throws ArrayIndexOutOfBoundsException {
  85.       if (index >= 0 && index < this.end - this.begin) {
  86.          return (String)this.lines.elementAt(this.begin + index);
  87.       } else {
  88.          throw new ArrayIndexOutOfBoundsException(index);
  89.       }
  90.    }
  91.  
  92.    public byte[] getBodyBytes() {
  93.       ByteArrayOutputStream bos = new ByteArrayOutputStream();
  94.  
  95.       for(int i = 0; i < this.getBodyLineCount(); ++i) {
  96.          decode(this.getBodyLine(i), bos);
  97.       }
  98.  
  99.       return bos.toByteArray();
  100.    }
  101.  
  102.    public int getPartCount() {
  103.       return this.parts == null ? 0 : this.parts.size() - 1;
  104.    }
  105.  
  106.    public MimeDecoder getPart(int index) {
  107.       if (index >= 0 && index < this.getPartCount()) {
  108.          int i = (Integer)this.parts.elementAt(index);
  109.          int j = (Integer)this.parts.elementAt(index + 1);
  110.          return new MimeDecoder(this, i + 1, j);
  111.       } else {
  112.          throw new ArrayIndexOutOfBoundsException(index);
  113.       }
  114.    }
  115.  
  116.    public String getType() {
  117.       return this.type;
  118.    }
  119.  
  120.    public String getName() {
  121.       return this.name;
  122.    }
  123.  
  124.    public String getEncoding() {
  125.       return this.encoding;
  126.    }
  127.  
  128.    public static String getStringName(String s) {
  129.       int p = s.indexOf(61);
  130.       return p == -1 ? null : s.substring(0, p);
  131.    }
  132.  
  133.    public static String getStringValue(String s) {
  134.       int p = s.indexOf(61);
  135.       String value;
  136.       if (p == -1) {
  137.          value = s;
  138.       } else {
  139.          value = s.substring(p + 1);
  140.       }
  141.  
  142.       value = value.trim();
  143.       if (value.length() > 1 && value.charAt(0) == '"' && value.charAt(value.length() - 1) == '"') {
  144.          value = value.substring(1, value.length() - 1);
  145.       }
  146.  
  147.       return value;
  148.    }
  149.  
  150.    private static int decode(char c) {
  151.       if (c >= 'A' && c <= 'Z') {
  152.          return c - 65;
  153.       } else if (c >= 'a' && c <= 'z') {
  154.          return c - 97 + 26;
  155.       } else if (c >= '0' && c <= '9') {
  156.          return c - 48 + 26 + 26;
  157.       } else {
  158.          switch (c) {
  159.             case '+':
  160.                return 62;
  161.             case '/':
  162.                return 63;
  163.             case '=':
  164.                return 0;
  165.             default:
  166.                throw new RuntimeException("Illegal MIME character '" + c + "'");
  167.          }
  168.       }
  169.    }
  170.  
  171.    private static void decode(String s, ByteArrayOutputStream bos) {
  172.       int i = 0;
  173.       int len = s.length();
  174.  
  175.       while(true) {
  176.          while(i < len && s.charAt(i) <= ' ') {
  177.             ++i;
  178.          }
  179.  
  180.          if (i == len) {
  181.             break;
  182.          }
  183.  
  184.          int tri = (decode(s.charAt(i)) << 18) + (decode(s.charAt(i + 1)) << 12) + (decode(s.charAt(i + 2)) << 6) + decode(s.charAt(i + 3));
  185.          bos.write(tri >> 16 & 255);
  186.          if (s.charAt(i + 2) == '=') {
  187.             break;
  188.          }
  189.  
  190.          bos.write(tri >> 8 & 255);
  191.          if (s.charAt(i + 3) == '=') {
  192.             break;
  193.          }
  194.  
  195.          bos.write(tri & 255);
  196.          i += 4;
  197.       }
  198.  
  199.    }
  200. }
  201.